package cn.sciento.config.client.api.impl;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;

import cn.sciento.config.client.api.ConfigClient;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.client.RestTemplate;

public class DefaultConfigClient implements ConfigClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultConfigClient.class);

    private static final String METADATA_CONTEXT_PATH = "CONTEXT";

    private static final String NOTIFY_ENDPOINT = "/choerodon/config";

    private final ExecutorService asyncExecutor = new ScheduledThreadPoolExecutor(4, (ThreadFactory) (new BasicThreadFactory.Builder())
            .namingPattern("refresh-config-pool-%d").daemon(true).build());

    private RestTemplate restTemplate = new RestTemplate();

    @Autowired
    private DiscoveryClient discoveryClient;

    public void publishConfig(String env, String serviceName, String version, String fileType, String content) {
        try {
            List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceName);
            if (instances.isEmpty()) {
                LOGGER.warn("Notify service[serviceCode={}] refresh route failed, this service is not UP", serviceName);
                return;
            }
            for (ServiceInstance noticeInstance : instances) {
                String contextPath = (String) noticeInstance.getMetadata().get("CONTEXT");
                String noticeUri = "http://" + noticeInstance.getHost() + ":" + noticeInstance.getPort();
                if (!StringUtils.isEmpty(contextPath))
                    noticeUri = noticeUri + "/" + contextPath;
                noticeUri = noticeUri + "/choerodon/config";
                String finalNoticeUri = noticeUri;
                this.asyncExecutor.submit(() -> this.restTemplate.put(finalNoticeUri, null));
                LOGGER.info("Notify service: {} refresh config success", serviceName);
            }
        } catch (Exception e) {
            LOGGER.warn("Notify service: {} refresh config failed", serviceName, e);
        }
    }
}
